#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

void priStr(unsigned char* buf, int len) {
	int i; 
	printf("\n");
	for (i = 0; i < len; i++) {
		//if (((i+1) % 20) == 0) printf("\n");
		//printf("0x[%02x]", buf[i]);
		printf("[%02x]", buf[i]);
		printf("%c", buf[i]);
	}
	printf("\n");
}

void get_random_str(unsigned char* buf, int len) {
	int l, c;
	srand((unsigned)time(0));
	for (l = 0; l < len; ++l) {
		switch(rand()%3){
			case 0:;c='A'+rand()%26;break;
			case 1:;c='a'+rand()%26;break;
			case 2:;c='0'+rand()%10;break;
		}
		buf[l] = c;
	}
}

void encode_mod_add(unsigned char* src, unsigned char* key, int len) {
	int i = 0;
	for (i = 0; i < len; ++i) {
		if ((src[i] & 0xFF) & 0x01)
			src[i] += key[i];
		else
			src[i] -= key[i];
	}
}

void decode_mod_add(unsigned char* src, unsigned char* key, int len) {
	int i = 0;
	for (i = 0; i < len; ++i) {
		if ((src[i] & 0xFF) & 0x01)
			src[i] += key[i];
		else
		   src[i] -= key[i];
	}
}

void creat_key(unsigned char* src, int len) {
	int i = 0;
	for (i = 0; i < len; ++i) {
		src[i] |= 0x01;
	}
}

void code_not_or(unsigned char* src, unsigned char* key, int len) {
	int i = 0;
	for (i = 0; i < len; ++i) {
		src[i] ^= key[i];
	}
}
static unsigned char check_sum(unsigned char* buf, int len) {
	unsigned int sum;
	for (sum = 0; len > 0; len--)
		sum += *buf++;       
	sum = (sum >> 8) + (sum & 0xFFFFFFFF);
	sum += (sum >> 8);                   
	return ~sum;                        
} 

int main() {
	unsigned char a[8] = {0};
	unsigned char k[4] = {0};
	get_random_str(a, 8);
	sleep(2);
	get_random_str(k, 4);
	creat_key(k, 4);

	printf("[MSG]:        \t");
	priStr(a, 8);
	printf("[KEY]:        \t");
	priStr(k, 4);

	encode_mod_add(a, k, 4);
	encode_mod_add(a+4, k, 4);
	code_not_or(a, k, 4);
	code_not_or(a+4, k, 4);
	printf("[Send msg]:   \t");
	priStr(a, 8);

	code_not_or(a, k, 4);
	code_not_or(a+4, k, 4);
	decode_mod_add(a, k, 4);
	decode_mod_add(a+4, k, 4);

	printf("[DECODE MSG]: \t");
	priStr(a, 8);
	unsigned char* x = "LKMDgc5iJd61MEWd231BLJVUNBC3460C";
	unsigned char xx[32] = {0};
	memcpy(xx, x, 32);
	printf("\n============================\n");
	priStr(xx, 32);
	xx[31] = 0x00;
	xx[31] = check_sum(xx, 32);
	printf("\n============================\n");
	priStr(xx, 32);
	return 0;
}
